﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using ArkanoidX.Objects;

namespace ArkanoidX.RacketStates
{
    class MultiballPlayer : NormalState
    {
        public MainGame _game;

        public MultiBall mball = null;

        public MultiballPlayer(Game game, Vector2 size, Rectangle regionInSource,
            Rectangle reachableArea)
            : base(game, size, regionInSource, reachableArea)
        {
            _game = (MainGame)game;
        }

        public MultiballPlayer(Game game, Vector2 size, Rectangle reachableArea)
            : base(game, size, reachableArea)
        {
            _game = (MainGame)game;
        }

        public MultiballPlayer(Game game, Rectangle reachableArea)
            : base(game, reachableArea)
        {
            _game = (MainGame)game;
        }

        public override TimeSpan LifeSpan
        {
            get
            {
                return new TimeSpan(0, 0, 5);
            }
        }

        public override void FadeOut()
        {
            if (mball != null && _game._level.Ball == mball)
            {
                Ball alive = mball.GetAlive();

                mball.RemoveFromGame();
                alive.AddToLayer(_game.BallLayer);

                _game._level.Ball = alive;
            }

            mball = null;

            base.Inactivate();
        }

        public override void Initiate(Racket.State lastState)
        {
            base._lastState = lastState;
            if (_lastState != null)
            {
                _pendingTransition = lastState.NeedsTransition;
                _lastState.InnerState = InternalState.Inactive;
            }
            this._internalState = InternalState.Starting;

            base.Initiate(lastState);
        }

        public override void FadingInUpdate(Racket racket, GameTime gameTime, Racket.State fadingOutState)
        {
            base.FadingInUpdate(racket, gameTime, fadingOutState);
        }

        public override void Update(Racket racket, GameTime gameTime)
        {
            bool starting = (this._internalState == InternalState.Starting);

            base.PreUpdate(racket, gameTime);

            MultiBall oldMBall = mball;

            if (starting)
            {
                if (mball != null)
                {
                    mball.RemoveFromGame();
                    mball = null;
                }
            }
            if (this._internalState == InternalState.FadingIn || this._internalState == InternalState.Active)
            {
                if (mball == null)
                {
                    Bricks bricks = _game._level.Bricks;

                    Ball oldBall = _game._level.Ball;

                    if (oldBall == null)
                    {
                        oldBall = oldMBall.GetAlive();
                    }
                    else
                    {
                        oldBall.RemoveFromGame();
                    }

                    if (oldBall is MultiBall)
                    {
                        oldBall = ((MultiBall)oldBall).GetAlive();
                    }

                    mball = new MultiBall(oldBall, 3);

                    _game._level.Ball = mball;

                    mball.AddToLayer(_game.BallLayer);

                    Matrix m0 = Utility.GetRotationMatrix(0.15f);
                    Matrix m1 = Utility.GetRotationMatrix(-0.15f);
                    Ball ball0 = mball.SubBalls[0];

                    mball.SubBalls[1].Position = ball0.Position;
                    mball.SubBalls[1].Velocity = new Vector2(
                        ball0.Velocity.X * m0.M11 + ball0.Velocity.Y * m0.M12,
                        ball0.Velocity.X * m0.M21 + ball0.Velocity.Y * m0.M22);

                    mball.SubBalls[2].Position = ball0.Position;
                    mball.SubBalls[2].Velocity = new Vector2(
                        ball0.Velocity.X * m1.M11 + ball0.Velocity.Y * m1.M12,
                        ball0.Velocity.X * m1.M21 + ball0.Velocity.Y * m1.M22);

                }
            }

            if ((_game._level.Ball == null || 
                _game._level.Ball._lifeState == Ball.LifeState.Dead) && mball != null)
            {
                _game._level.Ball = mball.GetAlive();
            }

            base.NormalUpdate(racket, gameTime);
        }
    }
}
